﻿using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using WorkFlowCore.Conditions;

namespace WorkFlowCore.UserSelectors
{
    public class UserSelectorManager
    {
        private static object objLock = new object();
        static UserSelectorManager()
        {
            AllUserSelectors = new List<UserSelector>();
            DefaultUserSelectorAndSelections = new Dictionary<string, List<string>>();
        }



        /// <summary>
        /// 所有用户选择器
        /// </summary>
        private static List<UserSelector> AllUserSelectors;
        /// <summary>
        /// 所有用户选择器
        /// </summary>
        public static IReadOnlyList<UserSelector> UserSelectors { get => AllUserSelectors; }
        private static Dictionary<string,List<string>> DefaultUserSelectorAndSelections { get; set; }
        public static void RegisterSelector(string selectorId, string selectorName, Type selectorType, string description)
        {
            lock (objLock)
            {
                if (AllUserSelectors.Where(s => s.Id == selectorId).Any())
                    return;
                //throw new Exception($"相同的选择器id[{selectorId}]已存在");
            }

            AllUserSelectors.Add(new UserSelector(selectorId, selectorName, selectorType, description));

            //标记默认的选择器记录下来
            var defaultSelectorAttr = selectorType.GetCustomAttribute<DefaultUserSelectorAttribute>();
            if (defaultSelectorAttr!=null)
            {
                if (!DefaultUserSelectorAndSelections.ContainsKey(selectorId))
                    DefaultUserSelectorAndSelections.Add(selectorId, new List<string>());

                var selection = defaultSelectorAttr.DefaultSelection;
                if (selection != null)
                    DefaultUserSelectorAndSelections[selectorId].Add(selection);
            }
        }
        /// <summary>
        /// 从 程序集注册
        /// </summary>
        /// <param name="assemblies"></param>
        public static void RegisterSelector(params Assembly[] assemblies)
        {
            foreach (var assembly in assemblies)
            {
                var types = assembly.GetTypes().Where(t => t.GetCustomAttribute<UserSelectorAttribute>() != null);

                foreach (var type in types)
                {
                    var attr = type.GetCustomAttribute<UserSelectorAttribute>();
                    var selectorId = type.FullName;
                    var selectorName = attr.Name ?? type.FullName;
                    RegisterSelector(selectorId, selectorName, type, attr.Description);
                }
            }
        }

        /// <summary>
        /// 从 程序集注册
        /// </summary>
        /// <param name="handler"></param>
        /// <param name="assemblies"></param>
        public static void RegisterSelector(IServiceCollection services, params Assembly[] assemblies)
        {
            foreach (var assembly in assemblies)
            {
                var types = assembly.GetTypes().Where(t => t.GetCustomAttribute<UserSelectorAttribute>() != null);

                foreach (var type in types)
                {
                    var attr = type.GetCustomAttribute<UserSelectorAttribute>();
                    var selectorId = type.FullName;
                    var selectorName = attr.Name ?? type.FullName;
                    RegisterSelector(selectorId, selectorName, type, attr.Description);
                    services.AddScoped(type);
                }
            }
        }

        /// <summary>
        /// 从 程序集注册
        /// </summary>
        /// <param name="handler"></param>
        /// <param name="types"></param>
        public static void RegisterSelector(IServiceCollection services, params Type[] types)
        {
            var _types = types.Where(t => t.GetCustomAttribute<UserSelectorAttribute>() != null);

            foreach (var type in _types)
            {
                var attr = type.GetCustomAttribute<UserSelectorAttribute>();
                var selectorId = type.FullName;
                var selectorName = attr.Name ?? type.FullName;
                RegisterSelector(selectorId, selectorName, type, attr.Description);
                services.AddScoped(type);
            }
        }


        /// <summary>
        /// 获取选择器
        /// </summary>
        /// <param name="selectorId"></param>
        /// <param name="selectorCreator"></param>
        /// <returns></returns>
        public virtual IUserSelector GetUserSelector(string selectorId)
        {
            var selector = AllUserSelectors.FirstOrDefault(s => s.Id == selectorId);
            if (selector == null) return null;
            try
            {
                return (IUserSelector)Activator.CreateInstance(selector.SelectorType); 
            }
            catch (Exception)
            {
                return null;
            }
        }

        /// <summary>
        /// 获取默认选择器id
        /// </summary>
        /// <returns></returns>
        public virtual List<string> GetDefaultUserSelectorIds()
        {
            if (DefaultUserSelectorAndSelections.Count > 0)
                return DefaultUserSelectorAndSelections.Select(item => item.Key).ToList();
            return new List<string>() { AllUserSelectors.FirstOrDefault().Id };
        }
        /// <summary>
        /// 获取默认的用户选项
        /// </summary>
        /// <param name="selectorId"></param>
        /// <returns></returns>
        public virtual List<string> GetDefaultSelectionIds(string selectorId)
        {
            if (DefaultUserSelectorAndSelections.ContainsKey(selectorId)) return DefaultUserSelectorAndSelections[selectorId];
            return new List<string> { GetUserSelector(selectorId).GetSelections()?.FirstOrDefault()?.Id };
        }
        /// <summary>
        /// 卸载
        /// </summary>
        /// <param name="conditionId"></param>
        public static void UnRegisterSelector(string selectorId)
        {
            lock (objLock)
            {
                if (AllUserSelectors.Where(s => s.Id == selectorId).Any())
                {
                    AllUserSelectors = AllUserSelectors.Where(s => s.Id != selectorId).ToList();
                }
            }
        }
    }
}
